import 'dart:convert';

import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:myapp/http/core/base_request.dart';
import 'package:myapp/http/sample/base/app_result_wrap.dart';

import '../../core/net_callback.dart';
import '../../core/net_response.dart';
import '../app_net_init.dart';
import 'app_net_response.dart';

abstract class AppBaseRequest<R> extends BaseRequest {
  void prepareRequest();

  bool _useLoading = false;

  AppBaseRequest<R> useLoading() {
    _useLoading = true;
    return this;
  }

  void _showLoading() {
    if (_useLoading) {
      EasyLoading.show();
    }
  }

  bool _useDefaultErr = false;

  AppBaseRequest<R> useDefaultErr() {
    _useDefaultErr = true;
    return this;
  }


  R onDataConvert(Map<String, dynamic>? netResult);

  /**
   * 异步
   * ================================================================
   */

  NetCallback<R>? _mCallback;

  AppBaseRequest setCallback(NetCallback<R>? callback) {
    _mCallback = callback;
    return this;
  }

  void enqueue() {
    prepareRequest();
    _showLoading();
    AppNetInit.mNetCore.enqueue(this);
  }

  Future<NetResponse<R>> execute() async {
    prepareRequest();
    _showLoading();

    Future<NetResponse<R>> r = AppNetInit.mNetCore.execute(this);
    if (_useDefaultErr) {
      r.then((value) {
        if (!value.isOk()) {
          EasyLoading.showError(value.msg ?? "unknow");
        }
      });
    }
    return r;
  }

  @override
  void onAsyncFinish() {
    if (_useLoading) {
      EasyLoading.dismiss();
    }
    _mCallback?.onFinish?.call();
  }

  @override
  void onAsyncSuccess(dynamic netResult) {
    Map<String, dynamic> reponseResult = json.decode(netResult);
    AppResultWrap wrap = AppResultWrap.fromJson(reponseResult);
    if (wrap.code == "SUCCESS") {
      _mCallback?.onSuccess?.call(onDataConvert(wrap.data));
    } else {
      onAsyncFail(wrap.code ?? "-7777", wrap.message ?? "unknow");
    }
  }

  @override
  void onAsyncFail(String code, String msg) {
    if (_useDefaultErr) {
      EasyLoading.showError(msg);
    }
    _mCallback?.onFail?.call(code, msg);
  }

  /**
   * 同步
   * ================================================================
   */

  @override
  void onSyncFinish() {
    if (_useLoading) {
      EasyLoading.dismiss();
    }
  }

  @override
  Future<NetResponse<T>> onSyncSuccess<T>(dynamic netResult) async {
    Map<String, dynamic> reponseResult = json.decode(netResult);
    AppResultWrap wrap = AppResultWrap.fromJson(reponseResult);
    if (wrap.code == "SUCCESS") {
      R data = onDataConvert(wrap.data);
      return Future.value(AppNetResponse(wrap.code, wrap.message, data as T));
    } else {
      return Future.value(AppNetResponse(wrap.code, wrap.message, null));
    }
  }

  @override
  Future<NetResponse<T>> onSyncFail<T>(String code, String msg) {
    return Future.value(AppNetResponse(code, msg, null));
  }



}
